﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MonitoringSettingsDialog.cs" company="YellowFish">
//   Copyright © YellowFish 2009
// </copyright>
// <summary>
//   Defines the MonitoringSettingsDialog type.
// </summary>
// <author>
// Roman "4ux-nbIx" Novitsky
// </author>
// --------------------------------------------------------------------------------------------------------------------

namespace OneNoteNotify
{
  #region Imported Namespaces


  using System;
  using System.Collections.Generic;
  using System.Windows.Forms;

  using YF.Controls;
  using YF.OneNote;
  using YF.OneNote.DataTypes;
  using YF.OneNoteNotify.Data;


  #endregion


  internal partial class MonitoringSettingsDialog: Form
  {
    #region Constants and Fields


    private readonly MonitoringSettings _settings;


    private NoteTreeNode _nodes;


    #endregion


    #region Constructors and Destructors


    public MonitoringSettingsDialog(MonitoringSettings settings)
    {
      _settings = settings;
      InitializeComponent();

      InitializeTree();
    }


    #endregion


    #region Public Methods


    public MonitoringSettings GetMonitoringSettings()
    {
      var monitoringSettings = new MonitoringSettings();
      var nodeMonitoringSettings = new List<NodeMonitoringSettings>();

      GetNodesToMonitor(_nodes, nodeMonitoringSettings);

      monitoringSettings.NodesToWatch.AddRange(nodeMonitoringSettings);

      return monitoringSettings;
    }


    #endregion


    #region Methods


    private static NoteTreeNode CreateNodes(NotesNode sourceNode)
    {
      var node = new NoteTreeNode(sourceNode);

      if (!(sourceNode is Page))
      {
        foreach (NotesNode sourceChildnode in sourceNode.Children)
        {
          NoteTreeNode childNode = CreateNodes(sourceChildnode);
          node.Nodes.Add(childNode);
        }
      }

      return node;
    }


    private static void GetNodesToMonitor(NoteTreeNode node, ICollection<NodeMonitoringSettings> nodeMonitoringSettings)
    {
      if (node.Checked)
      {
        var nodeSettings = new NodeMonitoringSettings();
        nodeSettings.NodeId = node.NotesItem.ID;
        nodeMonitoringSettings.Add(nodeSettings);

        return;
      }

      foreach (NoteTreeNode childNode in node.Nodes)
      {
        GetNodesToMonitor(childNode, nodeMonitoringSettings);
      }
    }


    private static void MarkChildNodes(TreeNode node)
    {
      foreach (TreeNode childNode in node.Nodes)
      {
        childNode.Checked = node.Checked;
        MarkChildNodes(childNode);
      }
    }


    private static void MarkParentNodes(TreeNode node)
    {
      if (node.Parent != null)
      {
        TreeNode parent = node.Parent;

        foreach (TreeNode child in parent.Nodes)
        {
          if (!child.Checked)
          {
            parent.Checked = false;
            break;
          }
        }

        MarkParentNodes(parent);
      }
    }


    private void TreeAfterCheck(object sender, TreeViewEventArgs e)
    {
      _tree.AfterCheck -= TreeAfterCheck;

      var settingsTreeNode = (NoteTreeNode)e.Node;

      MarkChildNodes(settingsTreeNode);
      MarkParentNodes(settingsTreeNode);

      _tree.AfterCheck += TreeAfterCheck;
    }


    private void BtnOkClick(object sender, EventArgs e)
    {
      DialogResult = DialogResult.OK;
      Close();
    }


    private void InitializeTree()
    {
      _nodes = CreateNodes(OneNote.Notes);
      _tree.Nodes.Add(_nodes);
      _tree.AfterCheck += TreeAfterCheck;

      MonitoringSettings monitoringSettings = _settings;
      if (monitoringSettings != null)
      {
        foreach (NodeMonitoringSettings nodeSettings in monitoringSettings.NodesToWatch)
        {
          NoteTreeNode node = _nodes.FindHierarchyNode(nodeSettings.NodeId);

          if (node != null)
          {
            node.Checked = true;
          }
        }
      }
    }


    #endregion
  }
}